#include <iostream>
#include <string>

// 展示C++17的折叠表达式

// 1. 一元右折叠：(pack op ...)
template<typename... Args>
auto sum_right_fold(Args... args) {
    return (args + ...);  // 相当于arg1 + (arg2 + (arg3 + ...))
}

// 2. 一元左折叠：(... op pack)
template<typename... Args>
auto sum_left_fold(Args... args) {
    return (... + args);  // 相当于(((arg1 + arg2) + arg3) + ...)
}

// 3. 二元右折叠：(pack op ... op init)
template<typename... Args>
auto sum_right_fold_init(Args... args) {
    return (args + ... + 0);  // 添加初始值0
}

// 4. 二元左折叠：(init op ... op pack)
template<typename... Args>
auto sum_left_fold_init(Args... args) {
    return (0 + ... + args);  // 添加初始值0
}

// 使用&&运算符的折叠表达式
template<typename... Args>
bool all_true(Args... args) {
    return (args && ...);  // 当所有参数都为true时返回true
}

// 使用||运算符的折叠表达式
template<typename... Args>
bool any_true(Args... args) {
    return (args || ...);  // 当任一参数为true时返回true
}

// 使用,运算符的折叠表达式来执行操作序列
template<typename... Args>
void print_all(Args... args) {
    (std::cout << ... << args);  // 顺序打印所有参数
}

// 在函数调用中使用折叠表达式
template<typename T, typename... Args>
void push_all_to(T& container, Args... args) {
    (container.push_back(args), ...);  // 将所有参数添加到容器
}

// 复杂示例：使用折叠表达式变换和处理参数包
template<typename... Args>
void debug_print(Args... args) {
    std::cout << "  参数个数: " << sizeof...(args) << ", 值: ";
    ((std::cout << args << ' '), ...);
    std::cout << '\n';
}

// 使用静态断言检查所有类型
template<typename... Args>
void check_all_integral() {
    static_assert((std::is_integral_v<Args> && ...), 
                 "所有参数必须是整数类型");
}

void demonstrate_fold_expressions() {
    std::cout << "  基本折叠表达式演示:\n";
    
    std::cout << "  右折叠求和: " << sum_right_fold(1, 2, 3, 4, 5) << '\n';
    std::cout << "  左折叠求和: " << sum_left_fold(1, 2, 3, 4, 5) << '\n';
    std::cout << "  带初始值的右折叠: " << sum_right_fold_init(1, 2, 3, 4, 5) << '\n';
    std::cout << "  带初始值的左折叠: " << sum_left_fold_init(1, 2, 3, 4, 5) << '\n';
    
    std::cout << "\n  逻辑运算符的折叠表达式:\n";
    std::cout << "  all_true(true, true, true): " << std::boolalpha 
              << all_true(true, true, true) << '\n';
    std::cout << "  all_true(true, false, true): " 
              << all_true(true, false, true) << '\n';
    std::cout << "  any_true(false, false, true): " 
              << any_true(false, false, true) << '\n';
    std::cout << "  any_true(false, false, false): " 
              << any_true(false, false, false) << '\n';
    
    std::cout << "\n  使用逗号运算符打印: ";
    print_all("Hello", ", ", "Fold", " ", "Expressions", "!");
    std::cout << '\n';
    
    std::cout << "\n  不同类型的参数包:\n";
    debug_print(42, 3.14, "字符串", 'c');
    
    // 展示空参数包处理
    std::cout << "  空参数包求和: " << sum_right_fold_init() << '\n';
    
    // 静态断言示例 - 编译期检查
    // check_all_integral<int, char, bool>();     // 可以编译
    // check_all_integral<int, double, bool>();   // 编译错误
    
    // 注意：折叠表达式需要参数包，这里演示使用多个字符串
    auto concat_strings = [](auto... args) {
      return (std::string("") + ... + args);
    };
    std::cout << "  使用折叠表达式连接字符串: " 
              << concat_strings("Hello", ", ", "Fold", " ", "Expressions", "!") << '\n';
} 